package main;

import java.io.IOException;
import java.net.UnknownHostException;
import side_server.Server;
import side_server.Server_Launch;
import talk_server.Talker;

public class Host {
	private enum Commands{LAUNCH,LISTFILES,LISTPEERS,STOP,JOINGROUP,LEAVEGROUP,SHAREFILES,HELP,SHOW};

	private Talker			talker;
	private String			msg;
	
	public Host(String[] args) throws IllegalArgumentException, IOException
	{
		super();
		
		String command = null;
		if(args.length>0) 
			command = args[0].toUpperCase();
		else
			help();
		
		switch (Commands.valueOf(command)) {
		case LAUNCH:
			launch(Integer.parseInt(args[1]),args[2]);
			break;
		case JOINGROUP:
			join(args[1],Integer.parseInt(args[2]),args[3],Integer.parseInt(args[4]));
			break;
		case LISTPEERS:
			listpeers(args[1],Integer.parseInt(args[2]));
			break;
		case LISTFILES:
			listfiles(args[1],Integer.parseInt(args[2]));
			break;
		case STOP:
			break;
		case LEAVEGROUP:
			leave(args[1],Integer.parseInt(args[2]),args[3],Integer.parseInt(args[4]));
			break;
		case SHAREFILES:
			share(args);
			break;
		case SHOW:
			Server_Launch.getInstance().showPeers();
			break;
		default:
			help();
			break;
		}
	}
	
	private void launch(int port, String folder)
	{
		new Launch(port, folder);
	}
	
	private void join(String ip1, int port1, String ip2, int port2) throws UnknownHostException, IOException
	{
		talker = new Talker(ip1,port1);
		talker.write("JOIN"); //Messaggio per il SocketManager
		msg = talker.read(); //Attendo risposta dal server (WHO)
		System.out.println("RECEIVED: " + msg);
		System.out.println("SENDING: " + ip2 + " " + port2);
		talker.write(ip2 + " " + port2); //Aggiungi questo peer alla lista
		msg = talker.read(); //Operazione eseguita
		System.out.println("RECEIVED: " + msg);
		talker.close();
		System.out.println("JOIN ESEGUITO");
	}
	
	private void listpeers(String ip, int port) throws UnknownHostException, IOException
	{
		talker = new Talker(ip, port);
		talker.write("LISTPEERS"); //Messaggio per il SocketManager
		String peers[] = talker.read().split(Server.SEP); //Formatto il risultato
		System.out.println("ELENCO PEERS:");
		System.out.println("----------------------------");
		for(int i=0;i<peers.length;i++)
		{
			System.out.println("   " + peers[i]);
		}
		System.out.println("----------------------------\n\n");
	}
	
	private void listfiles(String ip, int port) throws UnknownHostException, IOException
	{
		talker = new Talker(ip, port);
		talker.write("LISTFILES"); //Messaggio per il SocketManager
		String[] files = talker.read().split(Server.SEP); //Formatto il risultato
		System.out.println("ELENCO FILE:");
		System.out.println("----------------------------");
		for(int i=0;i<files.length;i++)
		{
			System.out.println("   " + files[i]);
		}
		System.out.println("----------------------------\n\n");
	}
	
	private void leave(String ip1, int port1, String ip2, int port2) throws UnknownHostException, IOException
	{	
		//Cancello la lista dei peers dal peer che si disconnette
		talker = new Talker(ip2,port2);
		System.out.println("*************************");
		System.out.println("* LEAVEGROUP            *");
		System.out.println("* FROM  : " + ip1 + ":" + port1);
		System.out.println("* REMOVE: " + ip2 + ":" + port2);
		System.out.println("*************************");
		System.out.println("SENDING CLEAR");
		talker.write("CLEARPEERS");
		talker.read();
		talker.close();
		//Cancello il peer dall'elenco
		talker = new Talker(ip1, port1);
		System.out.println("SENDING: LEAVE");
		talker.write("LEAVE"); //Messaggio per il SocketManager
		msg = talker.read();
		System.out.println("RECEIVED: " + msg); //Ricevuta richiesta (WHO)
		talker.write(ip2 + " " + port2); //Invio al server il peer da rimuovere
		System.out.println("REMOVE PEER " + ip2 + ":" + port2);
		msg = talker.read(); //Leggo l'OK
		talker.close();
		
		//Rimuovo il peer da tutti i server nel mio elenco.
		System.out.println("REMOVE PEER " + ip2 + ":" + port2 + " FROM ALL PEERS");
		talker = new Talker(ip1, port1);
		talker.write("LISTPEERS"); //Messaggio per il SocketManager
		String listPeers = talker.read(); //Formatto il risultato
		talker.close();
		String showList = listPeers.replace(Server.SEP, "\n");
		System.out.println("PEER LIST:\n" + showList);
		System.out.println("================================");
		String[] splitPeers = listPeers.split(Server.SEP); //Lista divisa in un array
		for(int i=0;i<splitPeers.length;i++)
		{
			String[] host = splitPeers[i].split(" ");
			System.out.println("CONNECT TO " + splitPeers[i]);
			talker = new Talker(host[0],Integer.parseInt(host[1]));
			System.out.println("SENDING: LEAVE");
			talker.write("LEAVE"); //Messaggio per il SocketManager
			msg = talker.read();
			System.out.println("RECEIVED: " + msg); //Ricevuta richiesta (WHO)
			talker.write(ip2 + " " + port2); //Invio al server il peer da rimuovere
			System.out.println("REMOVE PEER " + ip2 + ":" + port2);
			msg = talker.read(); //Leggo l'OK
			talker.close();
			System.out.println("=================================");
		}
	}
	
	private void share(String[] args) throws UnknownHostException, IOException
	{
		String  ip   = args[1];
		int     port = Integer.parseInt(args[2]);
		int counter  = 0;
		boolean running = true;
		talker = new Talker(ip, port); //Contatto il server
		talker.write("SHARE");
		talker.read(); //Aspetto conferma "OK"
		System.out.println("SHARING IN PROGRESS...");
		//Invio il nome del file al server
		while(running)
		{
			counter++;
			if(counter>10) running=false;
			if(counter>args.length-3) running=false;
			if(running)
			{
				try
				{
					System.out.println(counter + ") SENDING FILE TO SHARE: " + args[counter+3]);
					talker.write(args[counter+3]);
					if(talker.read().equals("STOP")) running=false;
				}catch (ArrayIndexOutOfBoundsException e)
				{
					System.out.println("FILE SEND");
				}
			}
		}
		talker.close();
	}
	
	private void help()
	{
		System.out.println("USAGE peer <command> <parameters>");
		System.out.println("list of commands:");
		System.out.println("   LAUNCH <localport> <localfolder>");
		System.out.println("   JOINGROUP <ip1> <port1> <ip2> <port2");
		System.out.println("   LEAVEGROUP <ip1> <port1> <ip2> <port2");
		System.out.println("   SHAREFILES <ip> <port> <file1> <file2> ... <file10> ");
		System.out.println("   LISTPEERS <ip> <port>");
		System.out.println("   LISTFILES <ip> <port>");
		System.exit(666);
	}	
}
